home *** CD-ROM | disk | FTP | other *** search
/ Collection of Tools & Utilities / Collection of Tools and Utilities.iso / tex / sspell14.zip / FILE.C < prev    next >
C/C++ Source or Header  |  1992-07-18  |  7KB  |  264 lines

  1. /* **************************************************************** */
  2. /*             sspell - similar to Unix spell                       */
  3. /*                        version 1.4                               */
  4. /*                                                                  */
  5. /* Author: Maurice Castro                                           */
  6. /* Release Date:  4 Jul 1992                                         */
  7. /* Bug Reports: maurice@bruce.cs.monash.edu.au                      */
  8. /*                                                                  */
  9. /* This code has been placed by the Author into the Public Domain.  */
  10. /* The code is NOT covered by any warranty, the user of the code is */
  11. /* solely responsible for determining the fitness of the program    */
  12. /* for their purpose. No liability is accepted by the author for    */
  13. /* the direct or indirect losses incurred through the use of this   */
  14. /* program.                                                         */
  15. /*                                                                  */
  16. /* Segments of this code may be used for any purpose that the user  */
  17. /* deems appropriate. It would be polite to acknowledge the source  */
  18. /* of the code. If you modify the code and redistribute it please   */
  19. /* include a message indicating your changes and how users may      */
  20. /* contact you for support.                                         */
  21. /*                                                                  */
  22. /* The author reserves the right to issue the official version of   */
  23. /* this program. If you have useful suggestions or changes for the  */
  24. /* code, please forward them to the author so that they might be    */
  25. /* incorporated into the official version                           */
  26. /*                                                                  */
  27. /* Please forward bug reports to the author via Internet.           */
  28. /*                                                                  */
  29. /* Contributors: mao@physics.su.oz.au                               */
  30. /*                                                                  */
  31. /* **************************************************************** */
  32.  
  33. /* This set of routines accesses and indexes the dictionary */
  34.  
  35. #include <stdio.h>
  36. #include <sys/types.h>
  37. #include <sys/stat.h>
  38. #include "strfn.h"
  39. #if !defined(pyr)
  40. #include <stdlib.h>
  41. #endif
  42. #include "iofn.h"
  43. #include "file.h"
  44. #include "error.h"
  45. #include "config.h"
  46. #include "utility.h"
  47.  
  48. struct indexelm
  49. {
  50.    char word[HASHWID];
  51.    unsigned long location;
  52.    };
  53.  
  54. struct indexelm findx[IDXSIZ];
  55.  
  56. FILE *f;
  57.  
  58. void initfile(dict)
  59. char *dict;
  60. {
  61.    f=fopen(dict,"rt");
  62.    if  (f == NULL)
  63.    {
  64.     fprintf(stderr, "Unable to open dictionary: %s\n", dict);
  65.     exit(1);
  66.     }
  67.    }
  68.  
  69. void closefile()
  70. {
  71.    fclose(f);
  72.    }
  73.  
  74. /* build the index */
  75. void buildindex()
  76. {
  77.     char instr[MAXSTR];
  78.     char prev[MAXSTR];
  79.     unsigned long lastprev;
  80.     unsigned long lastinstr;
  81.     unsigned long filesize;
  82.     long i;
  83.     long j;
  84.   
  85.     /* initialise the index array */ 
  86.     for (i=0; i < IDXSIZ; i++)
  87.       findx[i].location = 0; 
  88.  
  89.     /* put in the first entry, it has to be zero */
  90.     findx[0].location = ftell(f);
  91.     fgets(instr,MAXSTR-1,f);
  92.     strcpy(prev,instr);
  93.     i = 1;
  94.  
  95.     /* find the file length */
  96.     fseek(f, 0l, SEEK_END);
  97.     filesize = ftell(f);
  98.  
  99.     /* put the pointer back */
  100.     fseek(f, 0l, SEEK_SET);
  101.  
  102.     /* find the other entries */
  103.     while (!feof(f))
  104.     {
  105.        lastinstr = ftell(f);
  106.        if (fgets(instr,MAXSTR-1,f)==NULL)
  107.           break;
  108.        if (stricmp(instr,prev)<0)
  109.        {
  110.           errormesg("Error: In dictionary order! Re-sort dictionary",-2); 
  111.           exit(1);
  112.           }
  113.        if ((lastinstr*IDXSIZ)/ filesize > i)
  114.        {
  115.           strncpy(findx[i].word,instr,HASHWID-1);
  116.           findx[i].location = lastinstr;
  117.           i++;
  118.           }
  119.        strcpy(prev,instr);
  120.        }
  121.     /* guarantee that the list is full */
  122.     i--;     /* incremented so we decrement it */
  123.     for (j=i; j < IDXSIZ; j++)
  124.     {
  125.         /* copy the last good record to pad */
  126.         findx[j].location = findx[i].location;
  127.         strcpy(findx[j].word, findx[i].word);  
  128.         }
  129.     clearerr(f);
  130.     } 
  131.  
  132. int readindex(indx)
  133. char *indx;
  134. {
  135.    FILE *fi;
  136.    time_t time;
  137.    struct stat statbuf;
  138.    unsigned long t;
  139.  
  140.    fi = fopen(indx,"rb");
  141.    if (fi == NULL)
  142.       return(FAIL);
  143.    /* check that the modify times are concordant */
  144.    fread(&time,sizeof(time_t),1,fi);
  145.    fstat(fileno(f), &statbuf);
  146.    if (time != statbuf.st_mtime)
  147.    {
  148.       fclose(fi);                     /* Mike O'Carroll reminded me of the */
  149.       return(FAIL);                   /* need to close files on exiting this */
  150.       }                               /* routine. M. Castro 4/3/92 */
  151.    fread(&t,sizeof(long),1,fi);
  152.    if (t != IDXSIZ) 
  153.    {
  154.       fclose(fi);
  155.       return(FAIL);
  156.       }
  157.    fread(&t,sizeof(long),1,fi);
  158.    if (t != HASHWID) 
  159.    {
  160.       fclose(fi);
  161.       return(FAIL);
  162.       }
  163.    fread(findx,sizeof(struct indexelm),IDXSIZ,fi);
  164.    fclose(fi);
  165.    return(SUCCESS);
  166.    } 
  167.    
  168. void writeindex(indx)
  169. char *indx;
  170. {
  171.    FILE *fi;
  172.    struct stat statbuf;
  173.    unsigned long t;
  174.  
  175.    fi = fopen(indx,"wb");
  176.    if (fi == NULL)
  177.    {
  178.        fprintf(stderr, "Cannot create index: %s\n",indx);
  179.        return;
  180.        } 
  181.    /* set the modify time and write the file */
  182.    fstat(fileno(f), &statbuf);
  183.    fwrite(&(statbuf.st_mtime),sizeof(time_t),1,fi);
  184.    t = IDXSIZ;
  185.    fwrite(&t,sizeof(long),1,fi);
  186.    t = HASHWID;
  187.    fwrite(&t,sizeof(long),1,fi);
  188.    fwrite(findx,sizeof(struct indexelm),IDXSIZ,fi);
  189.    fclose(fi);
  190.    } 
  191.  
  192. int searchfile(match, entry)
  193. char *match;
  194. char *entry;
  195. {
  196.    char instr[MAXSTR];
  197.    char *stripped;
  198.    long i;
  199.    /* bsearch additions */
  200.    long up;
  201.    long down;
  202.    long avr;
  203.    int cmp;
  204.  
  205.    /* search through the list if something is there then fseek it */
  206. /*   i = 0;
  207.    while ((i < IDXSIZ) && (strnicmp(findx[i].word, match,HASHWID-1) <= 0)) 
  208.    {
  209.       i++;
  210.       }
  211.    i--; */   /* subtract one to look at the right location */
  212.  
  213.    /* bsearch */  
  214.    up = IDXSIZ;
  215.    down = 0;
  216.    while (1)
  217.    {
  218.        avr = (up+down)/2;
  219.        cmp =  strnicmp(findx[avr].word, match, HASHWID-1);
  220.        if (!cmp)
  221.        {
  222.            i = avr - 1;
  223.            break;
  224.            }
  225.        if (up - down < 2)
  226.        {
  227.            i = down;
  228.            break;
  229.            }
  230.        if (cmp < 0)
  231.        {
  232.            down = avr;
  233.            }
  234.        if (cmp > 0)
  235.        {
  236.            up = avr;
  237.            }
  238.        }
  239.    /* catch alls - the second one is not really needed */
  240.    if (i < 0)
  241.       i = 0; 
  242.    if (i > IDXSIZ)
  243.       i = IDXSIZ;
  244.    
  245.    fseek(f,findx[i].location,SEEK_SET);
  246.  
  247.    while (!feof(f))
  248.    {
  249.        if (fgets(instr,MAXSTR-1,f)==NULL)
  250.       break;
  251.        stripped = strip(instr,"\r\n");
  252.        if (stricmp(stripped, match) > 0)
  253.       return(FAIL);
  254.        if (!stricmp(stripped, match))
  255.        {
  256.        /* it matches send back the matching entry */
  257.        strcpy(entry, stripped);
  258.        return(SUCCESS);
  259.        }
  260.        }
  261.    clearerr(f);
  262.    return(FAIL);
  263.    }
  264.